class Vue {
    constructor(obj_instance) {
        this.$data = obj_instance.data;
        Observer(this.$data);
        Compile(obj_instance.el, this);
    }
}
// 数据劫持- 监听实例里的数据
function Observer(data_instance) {
    if (!data_instance || typeof data_instance !== 'object') {
        return;
    }
    const dependency = new Dependency();
    Object.keys(data_instance).forEach(key => {
        let value = data_instance[key];
        // console.log('value',value);
        Observer(value);//递归-子属性数据劫持
        Object.defineProperty(data_instance, key, {
            enumerable: true,
            configurable: true,
            get() {
                console.log(`访问了属性${key}->值：${value}`);
                //订阅者加入依赖实例的数组
                Dependency.temp && dependency.addSub(Dependency.temp);
                if (Dependency.temp) {
                    console.error(Dependency.temp);
                }
                return value;
            },
            set(newValue) {
                console.log(`属性${key} 的${value}修改为->${newValue}`);
                value = newValue;
                Observer(newValue);
                dependency.notify();
            }
        })
    })
}
// HTML模板解析，替换DOM内容
function Compile(element, vm) {
    vm.$el = document.querySelector(element);
    // console.log(vm);
    const fragment = document.createDocumentFragment();
    let child;
    while (child = vm.$el.firstChild) {
        fragment.append(child);
    }
    // console.log('fragment', fragment);
    fragment_compile(fragment);
    // 替换文档碎片内容
    function fragment_compile(node) {
        const pattern = /\{\{\s*(\S+)\s*\}\}/;
        if (node.nodeType === 3) {
            const result_regex = pattern.exec(node.nodeValue);
            const xxx = node.nodeValue;
            if (result_regex) {
                const array = result_regex[1].split('.');
                console.log(array);
                const value = array.reduce((total, current) => {
                    // console.log('current',current);
                    // console.log('total',total);
                    return total[current]
                }, vm.$data)
                node.nodeValue = xxx.replace(pattern, value);
                // 创建订阅者
                new Watcher(vm, result_regex[1], newValue => {
                    node.nodeValue = xxx.replace(pattern, newValue)
                })
                // console.log(value);
                // console.log(node.nodeValue);
                // console.log(result_regex);
                // console.log(vm.$data[result_regex[1]]);
            }
            // console.log(node);
            // console.log(node.nodeValue);
            return;
        }
        if (node.nodeType === 1 && node.nodeName === 'INPUT') {
            // console.log('node.attributes',node.attributes);
            const attr = Array.from(node.attributes);
            // console.log('attr',attr);
            attr.forEach(i => {
                if (i.nodeName === 'v-model') {
                    // console.log(i.nodeValue);
                    const value = i.nodeValue.split('.').reduce((total, current) => {
                        return total[current];
                    }, vm.$data);
                    node.value = value;
                    // 创建订阅者
                    new Watcher(vm, i.nodeValue, newValue => {
                        node.value = newValue;
                    })
                    node.addEventListener('input',e=>{
                        // 这种方式改，多层对象嵌套不生效
                        // 见html文档那里的注释内容
                        //['more','like']
                        const arr1=i.nodeValue.split('.');
                        console.log('arr1',arr1);
                        //['more']
                        const arr2=arr1.slice(0,arr1.length-1);
                        console.log('arr2',arr2);
                        // vm.$data.more
                        const final=arr2.reduce((total,current)=>{
                            return total[current];
                        },vm.$data)
                        console.log('final',final);
                        // vm.$data.more['like']=e.target.value
                        final[arr1[arr1.length-1]]=e.target.value;
                    })
                }
            })
        }
        // else {
        node.childNodes.forEach(child => {
            // console.log('child', child);
            fragment_compile(child)
        });
        // }
    }
    vm.$el.appendChild(fragment);

}
// 依赖-收集和通知订阅者
class Dependency {
    constructor() {
        this.subscribers = [];
    }
    addSub(sub) {
        this.subscribers.push(sub);
    }
    notify() {
        this.subscribers.forEach(sub => sub.update());
    }

}
// 订阅者
class Watcher {
    constructor(vm, key, callback) {
        this.vm = vm;
        this.key = key;
        this.callback = callback;
        //  临时属性-触发getter
        Dependency.temp = this;
        console.log(`用 ${key}属性创建订阅者`);
        key.split('.').reduce((total, current) => {
            return total[current]
        }, vm.$data);
        Dependency.temp = null;
    }
    update() {
        const value = this.key.split('.').reduce((total, current) => {
            return total[current]
        }, this.vm.$data);
        this.callback(value);
        // this.callback();
    }
}